home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / tptc17tc.zip / FMAP.PAS < prev    next >
Pascal/Delphi Source File  |  1988-03-25  |  5KB  |  294 lines

  1.  
  2. (*
  3.  * fmap - find symbols related to an address in a .MAP load
  4.  *        map generated by LINK or TMAP
  5.  *
  6.  * S.H.Smith, 27-jan-86
  7.  *
  8.  *)
  9.  
  10. {$g512,p512,c-}
  11.  
  12. const
  13.    version = 'FMAP 1.0 (1/26/87 SHS)';
  14.  
  15. type
  16.    anystring = string[80];
  17.  
  18. var
  19.    line:    anystring;
  20.    fd:      text[10240];
  21.    target:  anystring;
  22.    mapname: anystring;
  23.  
  24.  
  25. procedure abort_check;
  26. begin
  27.    if keypressed then
  28.    begin
  29.       writeln('aborted');
  30.       halt;
  31.    end;
  32. end;
  33.  
  34.  
  35. procedure parse_segments;
  36. begin
  37.    writeln('Segments');
  38.    repeat
  39.       readln(fd,line);
  40.    until length(line) < 20;
  41. end;
  42.  
  43.  
  44. procedure parse_by_name;
  45. begin
  46.    writeln('Names');
  47.    readln(fd,line);
  48.  
  49.    repeat
  50.       readln(fd,line);
  51.       abort_check;
  52.    until length(line) < 17;
  53. end;
  54.  
  55.  
  56. procedure parse_by_value;
  57. var
  58.    pr:      anystring;
  59.    ad:      anystring;
  60.    ppr:     anystring;
  61.    pad:     anystring;
  62.    pline:   anystring;
  63.  
  64. begin
  65.    writeln('Values');
  66.    readln(fd,line);
  67.    pad := '0000';
  68.    ppr := '';
  69.  
  70.    repeat
  71.       ad := copy(line,7,4);
  72.       pr := copy(line,18,99);
  73.       if (ppr <> '') and (target >= pad) and (target < ad) then
  74.          writeln(pad,'-',ad,' ',pline);
  75.  
  76.       pad := ad;
  77.       ppr := pr;
  78.       pline := line;
  79.  
  80.       readln(fd,line);
  81.       abort_check;
  82.    until length(line) < 17;
  83. end;
  84.  
  85.  
  86. procedure output_lines(name: anystring; first, last: integer);
  87. var
  88.    fd: text[1024];
  89.    n:  integer;
  90.    b:  anystring;
  91.  
  92. begin
  93.    writeln('Output lines ',first,'-',last,' from ',name);
  94.    assign(fd,name);
  95. {$i-}
  96.    reset(fd);
  97. {$i+}
  98.    if ioresult <> 0 then
  99.    begin
  100.       writeln('can''t find source file: ',name);
  101.       writeln('need lines ',first,'-',last);
  102.       halt;
  103.    end;
  104.  
  105. {$i-}
  106.    for n := 1 to first-1 do
  107.       readln(fd,b);
  108.  
  109.    for n := first to last+1 do
  110.    begin
  111.       writeln(n:6,'| ',b);
  112.       readln(fd,b);
  113.       abort_check;
  114.    end;
  115. {$i+}
  116.  
  117.    close(fd);
  118. end;
  119.  
  120.  
  121. var
  122.    name:    anystring;
  123.    ln:      integer;
  124.    ad:      anystring;
  125.    pln:     integer;
  126.    pad:     anystring;
  127.    first:   boolean;
  128.  
  129.    procedure check_match;
  130.    begin
  131.       writeln('   check match, ',pad,'-',ad,'  lines ',pln,'-',ln);
  132.  
  133.       if (pln <> 0) and (target >= pad) and (target < ad) then
  134.       begin
  135.          if first then
  136.          begin
  137.             writeln;
  138.             writeln('==============================');
  139.             writeln(name);
  140.             first := false;
  141.          end;
  142.  
  143.          if (ln-pln) < 20 then
  144.          begin
  145.             writeln('---------');
  146.             writeln(pad,'-',ad);
  147.             output_lines(name,pln,ln);
  148.          end
  149.          else
  150.          begin
  151.             writeln('---------');
  152.             writeln(pad,'-',ad,'  lines ',pln,'-',ln);
  153.          end;
  154.       end;
  155.    end;
  156.  
  157. procedure parse_line_numbers;
  158. var
  159.    i:       integer;
  160.    code:    integer;
  161.    buf:     anystring;
  162.  
  163. begin
  164.    writeln('Line numbers: ',line);
  165.  
  166.    i := pos('(',line) + 1;
  167.    name := '';
  168.    while line[i] <> ')' do
  169.    begin
  170.       name := name + line[i];
  171.       i := i + 1;
  172.    end;
  173.  
  174.    readln(fd,line);
  175.    writeln('name=[',name,']');
  176.  
  177.    pln := 0;
  178.    pad := '0000';
  179.    first := true;
  180.  
  181.    repeat
  182.       abort_check;
  183.  
  184.       while length(line) > 6 do
  185.       begin
  186.  
  187.          {extract the line number}
  188.          buf := copy(line,1,5);
  189.          while copy(buf,1,1) = ' ' do
  190.             delete(buf,1,1);
  191.          val(buf,ln,code);
  192.  
  193.          {extract the code address}
  194.          ad := copy(line,12,4);
  195.  
  196.          {remove the processed part of the line}
  197.          delete(line,1,17);
  198.  
  199.          {if target is between two lines, then print it out}
  200.          check_match;
  201.  
  202.          pad := ad;
  203.          pln := ln;
  204.       end;
  205.  
  206.       readln(fd,line);
  207.    until length(line) < 6;
  208.  
  209.    check_match;   {process the last line}
  210. end;
  211.  
  212.  
  213. procedure parse_others;
  214. begin
  215.    writeln('Other: ',line);
  216.    readln(fd,line);
  217. end;
  218.  
  219.  
  220. procedure parse_mapfile;
  221. begin
  222.    writeln('Scanning mapfile ',mapname);
  223.    writeln('for address ',target,':');
  224.    writeln;
  225.  
  226.    readln(fd,line);
  227.  
  228.    while not eof(fd) do
  229.    begin
  230.       if copy(line,1,30) = ' Start  Stop   Length Name    ' then
  231.          parse_segments
  232.       else
  233.       if copy(line,1,30) = '  Address         Publics by N' then
  234.          parse_by_name
  235.       else
  236.       if copy(line,1,30) = '  Address         Publics by V' then
  237.          parse_by_value
  238.       else
  239.       if copy(line,1,17) = 'Line numbers for ' then
  240.          parse_line_numbers
  241.       else
  242.          parse_others;
  243.  
  244.       abort_check;
  245.    end;
  246.  
  247.    close(fd);
  248. end;
  249.  
  250.  
  251. var
  252.    i: integer;
  253.  
  254. begin
  255.    writeln;
  256.    writeln(version);
  257.    writeln;
  258.  
  259.    if paramcount <> 2 then
  260.    begin
  261.       writeln('Usage: fmap MAPFILE TARGET_ADDRESS');
  262.       writeln('Finds references to TARGET_ADDRESS in MAPFILE.');
  263.       halt(1);
  264.    end;
  265.  
  266.    mapname := paramstr(1);
  267.    if pos('.',mapname) = 0 then
  268.       mapname := mapname + '.MAP';
  269.  
  270.    assign(fd,mapname);
  271. {$i-}
  272.    reset(fd);
  273. {$i+}
  274.    if ioresult <> 0 then
  275.    begin
  276.       writeln('can''t open mapfile: ',mapname);
  277.       halt;
  278.    end;
  279.  
  280.    target := paramstr(2);
  281.    for i := 1 to length(target) do
  282.       target[i] := upcase(target[i]);
  283.  
  284.    if length(target) <> 4 then
  285.    begin
  286.       writeln('TARGET_ADDRESS must be 4 hex digits');
  287.       halt;
  288.    end;
  289.  
  290.    parse_mapfile;
  291.    writeln;
  292. end.
  293.  
  294.